/*
 * $Id: ActTaskDAO.java,v 1.20 2009/11/02 21:29:20 navdeep_mahajan Exp $
 * 
 * Copyright (C) 2006 General Electric Company. All Rights Reserved.
 * 
 * This software is the confidential and proprietary information of the General
 * Electric Company (GE). You shall not disclose this software and shall use it
 * only in accordance with the terms of the license agreement you entered into
 * with GE.
 * 
 * GE MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
 * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
 * NON-INFRINGEMENT. GE SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
 * AS A RESULT OF USING, MODIFYING, OR DISTRIBUTING THIS SOFTWARE OR ITS
 * DERIVATIVES.
 */
package com.ge.healthcare.autosc.common.database.dao;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.ge.healthcare.autosc.common.ASCLogger;
import com.ge.healthcare.autosc.common.ASCUtil;
import com.ge.healthcare.autosc.common.database.pojo.ActRequest;
import com.ge.healthcare.autosc.common.database.pojo.ActTask;
import com.ge.healthcare.autosc.common.database.pojo.CfgCodeDetails;
import com.ge.healthcare.autosc.common.database.pojo.CfgTaskCategoryInfo;
import com.ge.healthcare.autosc.common.database.pojo.CfgTaskType;
import com.ge.healthcare.autosc.common.database.pojo.HstRequest;
import com.ge.healthcare.autosc.common.database.pojo.HstTask;
import com.ge.healthcare.autosc.common.pojo.TaskNResource;

/**
 * @author 212042764
 * 
 */
public class ActTaskDAO extends BaseDAO implements ITaskDAO {
	/**
	 * Eclipse generated
	 */
	private static final long serialVersionUID = 2797251704774157368L;
	private ICodeDetailsDAO codeDetailsDAO;

	public ActTaskDAO() {
		super(ActTask.TABLE_NAME);
	}

	public ActTask getTaskByID(Long taskId) {
		Object request = findObjectByID(ActTask.COL_TASK_ID, taskId);
		if (!ASCUtil.isNullOrEmptyObject(request)) {
			return (ActTask) request;
		}
		return null;
	}

	public ArrayList<ActTask> getTasks(ActRequest request) {
		return getTasksByRequestId(request.getRequestId());
	}

	@SuppressWarnings("unchecked")
	public ArrayList<ActTask> getTasksByRequestId(Long requestId) {
		return (ArrayList) findByProperty(ActTask.COL_REQUEST_ID, requestId);
	}
	
	/**
	 * Returns list of tasks by code name
	 * @param codeName
	 * @return
	 */
	public List<ActTask> getTasksByCodeNameAndStepTypeId(String codeName, Long stepTypeId){
		CfgCodeDetails codeDetails = codeDetailsDAO.getUniqueCodedetailsByCodeName(codeName);
		if (ASCUtil.isNullOrEmptyObject(codeDetails)){
			return null;
		}
		Map<String, Object> whereClause = new HashMap<String, Object>();
		whereClause.put(ActTask.COL_CODE_ID, codeDetails.getCodeId());
		whereClause.put(ActTask.COL_STEP_TYPE_ID, stepTypeId);
		List<?> rtvdTasks = this.findByProperties(whereClause);
		if (ASCUtil.isNullOrEmptyList(rtvdTasks)){
			return null;
		}
		List<ActTask> tasksByCodeLst = new ArrayList<ActTask>();
		for (Object rtvdTask :  rtvdTasks){
			tasksByCodeLst.add((ActTask)rtvdTask);
		}
		return tasksByCodeLst;
	}

	/**
	 * Create and Save ActTask object from request and taskType
	 * 
	 * @param request
	 * @param taskType
	 * @return
	 */
	public ActTask initActTask(ActRequest request, CfgTaskType taskType,
			ActTask parentTask, String codeName) {
		String methodName = "initActTask";

		ActTask task = new ActTask(request, taskType);
		task.setFailedCount(0L);
		CfgCodeDetails code = codeDetailsDAO
				.getUniqueCodedetailsByCodeName(codeName);
		task.setCodeId(code.getCodeId());
		task.setExtAutosc(taskType.getExtAutosc());
		task.setPriority(taskType.getPriority());
		task.setExpireDate();
		task.setStartTime();
		if (parentTask != null && parentTask.getTaskId() != null) {
			task.setParentId(parentTask.getTaskId());
		} else {
			ASCLogger.debug(this.getClass(), methodName,
					"No Parent Task Recorded for " + task + " for Request: "
							+ request + " and TaskType: " + taskType);
		}

		ASCLogger.debug(this.getClass(), methodName, "Created Child Task: "
				+ task + " for Request: " + request + " and TaskType: "
				+ taskType);
		this.save(task);
		return task;
	}

	/**
	 * Does the same thing as setCodeDetails but in separate transaction. NO
	 * logic should be placed here unless it is related to the transaction.
	 * 
	 * @param task
	 * @param codeVal
	 */
	public Long setCodeDetailsAlways(ActTask task, String codeVal) {
		return setCodeDetails(task, codeVal);
	}

	/**
	 * Update a task with the status code
	 * 
	 * @param task
	 * @param codeVal
	 */
	public Long setCodeDetails(ActTask task, String codeVal) {
		CfgCodeDetails code = codeDetailsDAO
				.getUniqueCodedetailsByCodeName(codeVal);
		if (ASCUtil.isNullOrEmptyObject(code)) {
			ASCLogger.error(this.getClass(), "setCodeDetails",
					"No code id defined for " + codeVal);
			return null;
		} else {
			task.setCodeId(code.getCodeId());
			this.save(task);
		}
		return code.getCodeId();
	}

	public TaskNResource getTaskNResource(Long taskId) {
		ActTask task = getTaskByID(taskId);
		if (ASCUtil.isNullOrEmptyObject(task)) {
			// Do not throw here
			StringBuffer msg = new StringBuffer();
			msg.append("Invalid Task Id: ").append(taskId);
			ASCLogger.error(this.getClass(), "getTaskNResource by Id",
					new StringBuffer().append(msg));
			return null;
		} else {
			return getTaskNResource(task);
		}

	}

	public TaskNResource getTaskNResource(ActTask task) {
		StringBuffer query = new StringBuffer();
		query.append("Select aTask.").append(ActTask.COL_TASK_ID);
		query.append(", aTask.").append(ActTask.COL_PRIORITY);
		query.append(", aRequest.").append(ActRequest.COL_PORT_MASTER);
		query.append(", aRequest.").append(ActRequest.COL_MODEM_AREA_CODE);
		query.append(", aRequest.").append(ActRequest.COL_MODEM_NUMBER);
		query.append(", aRequest.").append(ActRequest.COL_SERVICE_CENTER);
		query.append(", aTaskCategory.").append(
				CfgTaskCategoryInfo.COL_TASK_CATEGORY);
		query.append(" from ");
		query.append(ActTask.TABLE_NAME).append(" as aTask , ");
		query.append(ActRequest.TABLE_NAME).append(" as aRequest , ");
		query.append(CfgTaskCategoryInfo.TABLE_NAME).append(
				" as aTaskCategory , ");
		query.append(CfgTaskType.TABLE_NAME).append(" as aTaskType ");
		query.append(" where ");
		query.append(" aTask.").append(ActTask.COL_REQUEST_ID).append(" = ");
		query.append(" aRequest.").append(ActRequest.COL_REQUEST_ID);
		query.append(" and ");
		query.append(" aTask.").append(ActTask.COL_TASK_TYPE).append(" = ");
		query.append(" aTaskType.").append(CfgTaskType.COL_NAME);
		query.append(" and ");
		query.append(" aTaskType.").append(CfgTaskType.COL_TASK_CATEGORY_ID)
				.append(" = ");
		query.append(" aTaskCategory.").append(
				CfgTaskCategoryInfo.COL_TASK_CATEGORY_ID);
		query.append(" and ");
		query.append(" aTask.").append(ActTask.COL_TASK_ID).append(" = ?");

		logger.debug("query: " + query.toString() + " value: "
				+ task.getTaskId());
		List<?> values = getHibernateTemplate().find(query.toString(),
				task.getTaskId());
		TaskNResource taskNR = null;
		if (!ASCUtil.isNullOrEmptyList(values)) {
			int i = 0;
			Object[] list = (Object[]) values.get(0);
			taskNR = new TaskNResource();
			taskNR.setTaskId((Long) list[i++]);
			taskNR.setPriority((Long) list[i++]);
			taskNR.setPortMaster((String) list[i++]);
			taskNR.setPhoneNumber(list[i++], list[i++]);
			taskNR.setServiceCenter((String) list[i++]);
			taskNR.setCategory((String) list[i++]);
			taskNR.setActTask(task);
		}else{
			taskNR = this.getTaskNResourceFromHistory(task);
		}
		return taskNR;
	}

	public TaskNResource getTaskNResourceFromHistory(ActTask task) {
		StringBuffer query = new StringBuffer();
		query.append("Select aTask.").append(ActTask.COL_TASK_ID);
		query.append(", aTask.").append(ActTask.COL_PRIORITY);
		query.append(", aRequest.").append(ActRequest.COL_PORT_MASTER);
		query.append(", aRequest.").append(ActRequest.COL_MODEM_AREA_CODE);
		query.append(", aRequest.").append(ActRequest.COL_MODEM_NUMBER);
		query.append(", aRequest.").append(ActRequest.COL_SERVICE_CENTER);
		query.append(", aTaskCategory.").append(
				CfgTaskCategoryInfo.COL_TASK_CATEGORY);
		query.append(" from ");
		query.append(HstTask.TABLE_NAME).append(" as aTask , ");
		query.append(HstRequest.TABLE_NAME).append(" as aRequest , ");
		query.append(CfgTaskCategoryInfo.TABLE_NAME).append(
				" as aTaskCategory , ");
		query.append(CfgTaskType.TABLE_NAME).append(" as aTaskType ");
		query.append(" where ");
		query.append(" aTask.").append(ActTask.COL_REQUEST_ID).append(" = ");
		query.append(" aRequest.").append(ActRequest.COL_REQUEST_ID);
		query.append(" and ");
		query.append(" aTask.").append(ActTask.COL_TASK_TYPE).append(" = ");
		query.append(" aTaskType.").append(CfgTaskType.COL_NAME);
		query.append(" and ");
		query.append(" aTaskType.").append(CfgTaskType.COL_TASK_CATEGORY_ID)
				.append(" = ");
		query.append(" aTaskCategory.").append(
				CfgTaskCategoryInfo.COL_TASK_CATEGORY_ID);
		query.append(" and ");
		query.append(" aTask.").append(ActTask.COL_TASK_ID).append(" = ?");

		logger.debug("query: " + query.toString() + " value: "
				+ task.getTaskId());
		List<?> values = getHibernateTemplate().find(query.toString(),
				task.getTaskId());
		TaskNResource taskNR = null;
		if (!ASCUtil.isNullOrEmptyList(values)) {
			int i = 0;
			Object[] list = (Object[]) values.get(0);
			taskNR = new TaskNResource();
			taskNR.setTaskId((Long) list[i++]);
			taskNR.setPriority((Long) list[i++]);
			taskNR.setPortMaster((String) list[i++]);
			taskNR.setPhoneNumber(list[i++], list[i++]);
			taskNR.setServiceCenter((String) list[i++]);
			taskNR.setCategory((String) list[i++]);
			taskNR.setActTask(task);
		}
		return taskNR;
	}

	/**
	 * @see com.ge.healthcare.autosc.common.database.dao.BaseDAO#save(java.lang.Object)
	 */
	public void save(Object pojo) {
		super.save(pojo);
	}

	/**
	 * @see com.ge.healthcare.autosc.common.database.dao.IRequestTypeDAO#saveAlways(java.lang.Object)
	 */
	public void saveAlways(Object pojo) {
		super.save(pojo);
	}

	/**
	 * @see com.ge.healthcare.autosc.common.database.dao.BaseDAO#deleteByID(java.lang.Object)
	 */
	public void deleteByID(Object pojo) {
		super.deleteByID(pojo);
	}

	/**
	 * @see com.ge.healthcare.autosc.common.database.dao.BaseDAO#refresh(java.lang.Object)
	 */
	public void refresh(Object pojo) {
		super.refresh(pojo);
	}

	/**
	 * @param codeDetailsDAO
	 *            the codeDetailsDAO to set
	 */
	public void setCodeDetailsDAO(ICodeDetailsDAO codeDetailsDAO) {
		this.codeDetailsDAO = codeDetailsDAO;
	}
}
